/**
 * 
 */
package com.wilmar.process.web.actions;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.wilmar.common.util.PageinationEntity;
import com.wilmar.process.core.ProcessSystemDeclareKeys;
import com.wilmar.process.core.services.api.ISystemHistoryProcessInstanceService;
import com.wilmar.process.core.services.api.ISystemProcessInstanceService;
import com.wilmar.process.core.services.spi.IProcessInstanceKeyGenerator;
import com.wilmar.process.entity.User;
import com.wilmar.process.entity.query.HistoryProcessInstanceQueryObject;
import com.wilmar.process.entity.vo.HistoryProcessInstanceVO;
import com.wilmar.process.enumerate.EnumProcessInstanceState;
import com.wilmar.process.exception.DirtyDataException;
import com.wilmar.process.exception.NoUserSessionException;
import com.wilmar.process.exception.PermissionDeniedException;
import com.wilmar.process.system.ProcessSystem;

/**
 * @author MaKuBEX E-mail:makubexnet@gmail.com
 * @version 1.0.0 at Aug 3, 2009 1:45:14 PM
 * 
 */
public class ProcessInstanceAction extends ProcessActionSupport {
	protected static final String ACTION_RESULT_SEARCH = "search";
	protected static final String ACTION_RESULT_LIST = "list";
	protected static final String ACTION_RESULT_LISTACTION = "list-action";
	protected static final String ACTION_RESULT_IMAGE = "image";
	protected static final String ACTION_RESULT_IMAGE_PAGE = "image-page";
	protected static final String ACTION_RESULT_SUCCESS_NEWINST = "success-newinst";

	/**
	 * @serialField
	 */
	private static final long serialVersionUID = -8892283507744028517L;

	protected ISystemProcessInstanceService systemProcessInstanceService;
	protected ISystemHistoryProcessInstanceService systemHistoryProcessInstanceService;

	protected List<HistoryProcessInstanceVO> historyProcessInstanceVOList;
	protected InputStream imageStream;
	protected Map<String, String> processInstanceStateSelection;

	protected HistoryProcessInstanceQueryObject historyProcessInstanceQueryObject;

	/**
	 * @return the systemProcessInstanceService
	 */
	public ISystemProcessInstanceService getSystemProcessInstanceService() {
		return systemProcessInstanceService;
	}

	/**
	 * @param systemProcessInstanceService
	 *            the systemProcessInstanceService to set
	 */
	public void setSystemProcessInstanceService(
			ISystemProcessInstanceService systemProcessInstanceService) {
		this.systemProcessInstanceService = systemProcessInstanceService;
	}

	public String doStopProcessInstance() throws PermissionDeniedException, NoUserSessionException {
		User starter = super.getCurrentUser();
		this.systemProcessInstanceService.stopProcessInstanceById(
				super.processInformation.getProcessInstanceId(), starter);
		return ACTION_RESULT_SUCCESS_NEWINST;
	}

	public String doSearchForward() {
		this.processInstanceStateSelection = new HashMap<String, String>();
		for (EnumProcessInstanceState state : EnumProcessInstanceState.values()) {
			this.processInstanceStateSelection.put(state.name(), state.name());
		}
		return ACTION_RESULT_SEARCH;
	}

	public String doGetCommittedProcessInstanceList() throws IOException, NoUserSessionException {
		User starter = super.getCurrentUser();
		if (super.pageination == null)
			super.pageination = new PageinationEntity(0,
					ProcessSystemDeclareKeys.SYSTEM_DEFAULT_PAGEINATION_LIMIT);
		if (this.historyProcessInstanceQueryObject != null) {
			this.historyProcessInstanceQueryObject
					.setPageination(super.pageination);
		}
		this.historyProcessInstanceVOList = this.systemHistoryProcessInstanceService
				.getListUsersCommitedProcessInstance(starter,
						this.historyProcessInstanceQueryObject);
		Collections.sort(this.historyProcessInstanceVOList);
		return ACTION_RESULT_LIST;
	}

	public String doInstanceImageForward() {
		return ACTION_RESULT_IMAGE_PAGE;
	}

	public String doStartProcessInstance() throws PermissionDeniedException,
			DirtyDataException, InstantiationException, IllegalAccessException,
			ClassNotFoundException, NoUserSessionException {
		User starter = super.getCurrentUser();
		String pikey = super.processInformation.getProcessInstanceKey();
		if (pikey == null
				&& super.processInformation.getProcessInstanceKeyGenerator() != null) {
			IProcessInstanceKeyGenerator keyGenerator = null;
			if (ProcessSystem.webAppContext
					.containsBean(super.processInformation
							.getProcessInstanceKeyGenerator())) {
				keyGenerator = (IProcessInstanceKeyGenerator) ProcessSystem.webAppContext
						.getBean(super.processInformation
								.getProcessInstanceKeyGenerator());
			} else {
				keyGenerator = (IProcessInstanceKeyGenerator) Class.forName(
						super.processInformation
								.getProcessInstanceKeyGenerator())
						.newInstance();
			}
			pikey = keyGenerator.generateProcessInstanceKey(super.request
					.getParameterMap(), starter);
			super.processInformation.setProcessDefinitionKey(pikey);
		}
		if (super.processInformation.getProcessDefinitionId() != null
				&& super.processInformation.getProcessDefinitionId().trim()
						.length() != 0) {
			super.processInformation
					.setProcessInstanceId(this.systemProcessInstanceService
							.startProcessInstanceByIdWithVariable(
									super.processInformation
											.getProcessDefinitionId(), pikey,
									this.request.getParameterMap(), starter));
		} else if (super.processInformation.getProcessDefinitionKey() != null
				&& super.processInformation.getProcessDefinitionKey().trim()
						.length() != 0) {
			super.processInformation
					.setProcessInstanceId(this.systemProcessInstanceService
							.startProcessInstanceByKeyWithVariable(
									super.processInformation
											.getProcessDefinitionKey(), pikey,
									this.request.getParameterMap(), starter));
		} else {
			throw new DirtyDataException(
					"Here is no process definition id or process definition key!");
		}
		return ACTION_RESULT_SUCCESS_NEWINST;
	}

	/**
	 * @return the historyProcessInstanceVOList
	 */
	public List<HistoryProcessInstanceVO> getHistoryProcessInstanceVOList() {
		return historyProcessInstanceVOList;
	}

	/**
	 * @param historyProcessInstanceVOList
	 *            the historyProcessInstanceVOList to set
	 */
	public void setHistoryProcessInstanceVOList(
			List<HistoryProcessInstanceVO> historyProcessInstanceVOList) {
		this.historyProcessInstanceVOList = historyProcessInstanceVOList;
	}

	/**
	 * @return the imageStream
	 */
	public InputStream getImageStream() {
		return imageStream;
	}

	/**
	 * @param imageStream
	 *            the imageStream to set
	 */
	public void setImageStream(InputStream imageStream) {
		this.imageStream = imageStream;
	}

	/**
	 * @return the systemHistoryProcessInstanceService
	 */
	public ISystemHistoryProcessInstanceService getSystemHistoryProcessInstanceService() {
		return systemHistoryProcessInstanceService;
	}

	/**
	 * @param systemHistoryProcessInstanceService
	 *            the systemHistoryProcessInstanceService to set
	 */
	public void setSystemHistoryProcessInstanceService(
			ISystemHistoryProcessInstanceService systemHistoryProcessInstanceService) {
		this.systemHistoryProcessInstanceService = systemHistoryProcessInstanceService;
	}

	/**
	 * @return the historyProcessInstanceQueryObject
	 */
	public HistoryProcessInstanceQueryObject getHistoryProcessInstanceQueryObject() {
		return historyProcessInstanceQueryObject;
	}

	/**
	 * @param historyProcessInstanceQueryObject
	 *            the historyProcessInstanceQueryObject to set
	 */
	public void setHistoryProcessInstanceQueryObject(
			HistoryProcessInstanceQueryObject historyProcessInstanceQueryObject) {
		this.historyProcessInstanceQueryObject = historyProcessInstanceQueryObject;
	}

	/**
	 * @return the processInstanceStateSelection
	 */
	public Map<String, String> getProcessInstanceStateSelection() {
		return processInstanceStateSelection;
	}

	/**
	 * @param processInstanceStateSelection
	 *            the processInstanceStateSelection to set
	 */
	public void setProcessInstanceStateSelection(
			Map<String, String> processInstanceStateSelection) {
		this.processInstanceStateSelection = processInstanceStateSelection;
	}
}
